package com.mvc.framework.scheduling;

import java.lang.reflect.Method;

import org.apache.log4j.Logger;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.SchedulerException;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.quartz.JobDetailBean;

import com.mvc.ProjectConstants;

public class ExtendJobDetailFactoryBean extends JobDetailBean{

	private static final long serialVersionUID = -3746466769752873252L;

	public ExtendJobDetailFactoryBean(){
		//The default is statefull
		setJobClass(StateFulJob.class);
	}

	public static class StateLessJob implements org.quartz.Job{

		protected final Logger logger = Logger.getLogger(StateLessJob.class);

		//Bean factory
		private ApplicationContext applicationContext;

		private ApplicationContext getApplicationContext(JobExecutionContext context) throws SchedulerException {
			if(applicationContext==null){
				applicationContext = (ApplicationContext)context.getScheduler().getContext().get("applicationContext");
			}
			return applicationContext;
		}

		public void execute(JobExecutionContext context) throws JobExecutionException {
			String jobName = context.getJobDetail().getName();
			if(logger.isDebugEnabled()){
				logger.debug("Task:'" + jobName + "' begin at " + ProjectConstants.PROJECT_NAME);
			}
			try {
				String targetObject = context.getJobDetail().getJobDataMap().getString("targetObject");
				String targetMethod = context.getJobDetail().getJobDataMap().getString("targetMethod");
				Object otargetObj = getApplicationContext(context).getBean(targetObject);
				Method m = otargetObj.getClass().getMethod(targetMethod, new Class[] {});
				m.invoke(otargetObj, new Object[] {});
				logger.info("Task:'" + jobName + "' execute successfully at " + ProjectConstants.PROJECT_NAME);
			} catch (Exception e) {
				logger.error("Task '" + jobName + "' can not execute successfully at " + ProjectConstants.PROJECT_NAME,e);
			}
		}
	 }

	 public static class StateFulJob extends StateLessJob implements org.quartz.StatefulJob  {
		 protected final Logger logger = Logger.getLogger(StateFulJob.class);
	 }

	public void setConcurrent(boolean concurrent) {
		setJobClass(concurrent?StateLessJob.class:StateFulJob.class);
	}
}
